
#include <iostream>

using namespace std;

// 关于C++继承
// 继承的限定
// 关于切片
// 继承后的默认成员函数
// 友元关系不能继承
// 继承与静态成员的关系: 基类定义了 static 静态成员，则整个继承体系只有一个这样的成员
// 单继承，多继承
// 菱形继承：出现问题：产生冗余，以及继承的二义性: virtual虚化

//class A
//{
//public:
//    int _a;
//
//    A(int a = 1, int b = 1, int c = 1)
//        :_a(a)
//         ,_b(b)
//         ,_c(c)
//    {}
//
//    void print()
//    {
//        cout << _a << ' ' << _b << ' ' << _c;
//    }
//
//private:
//    int _b;
//
//protected:
//    int _c;
//};
//
//class B : public A
//{
//public:
//
//    B()
//        :A(0, 0, 0)
//         ,_n(0)
//         ,_m(0)
//    {}
//
//    B(int a, int b, int c, int n, int m)
//        :A(a, b, c)
//         ,_n(n)
//         ,_m(m)
//    {}
//
//    void print()
//    {
//        // _b 不能被使用：类内类外都不行，因为他在父类是私有
//        //cout << "A-a: " << _a << "  A-b: " << _b << "  A-c: " << _c << endl;
//        cout << "  A-a: " << _a << "  A-c: " << _c << endl;
//        cout << "B-n: " << _n << "  B-m: " << _m << endl;
//    }
//
//protected:
//    int _n;
//    int _m;
//};


//////////////////////////////////////////

// 继承的默认成员函数问题
// 编译器产生的默认构造函数性质不变，唯一一点就是会调用父类的构造函数
// 拷贝函数和赋值重载也是一样
// 注意析构函数特殊化：子类析构函数调用结束后会自动调用父类的析构函数，所以不需要自己显示调用

class A
{
public:
    
    A(int a = 0)
        :_a(a)
    {
        cout << "A(构造)" << endl;
    }
    
    // 可以不写，默认生成的就够用
    A(const A& aa)
        :_a(aa._a)
    {
        cout << "A(拷贝构造)" << endl;
    }

    // 可以不写，默认生成的就够用
    A& operator=(const A& aa)
    {
        cout << "operator=(A赋值)" << endl;
        _a = aa._a;
        return *this;
    }
    
    // 析构函数也可以不写，对内置类型不处理
    ~A()
    {
        cout << "~A(析构)" << endl;

        _a = 0;
    }


protected:
    int _a;
};

class B : public A
{
public:

    B(int a = 0, int b = 0)
        :A(a)  // 这里只是语法是这样写的，与匿名对象的语法相同，但与匿名对象无关，这样写表示显示调用A的构造函数
         ,_b(b)
    {
        cout << "B(构造)" << endl;
    }

    B(const B& b)
        :A(b)  // 这里切片，将A的部分切开去显示调用A的拷贝构造
         ,_b(b._b)
    {
        cout << "B(拷贝构造)" << endl;
    }

    B& operator=(const B& b)
    {
        A::operator=(b); // 切片
        _b = b._b;

        cout << "operator=()" << endl;

        return *this;
    }

    // 不用显示调用A的析构
    ~B()
    {
        _b = 0;
        cout << "~B(析构)" << endl;
    } // 末尾编译器会自动调用A的析构

    // 根据内存储存顺序来看
    // B类成员后构造先析构
    // A类成员先构造后析构

    void print()
    {
         cout << "A: " << _a << " B: " << _b << endl;
    }

protected:
    int _b;
};

int main()
{
//    B b1;
//    b1.print();
//
//    B b2(1,2,3,4,5);
//    b2.print();
//
//    b2.A::print();

    B b1;

    B b2(10, 20);

    b1.print();
    b2.print();

    return 0;
}
